/*
   @Copyright:LibreOJ
   @Author:   tjyemail
   @Problem:  https://loj.ac/problem/101
   @Language: C++
   @Datetime: 20-08-14 14:07
   */
// arguement path - Edmonds-Karp, time O(V*E^2) 125ms

#include <bits/stdc++.h>
using namespace std;

#define VERTEX 102
int paths[VERTEX]; // pre-node
long long caps[VERTEX][VERTEX]; // a->b capacity
long long flows[VERTEX]; // current available flow s->k

inline bool findpath(int v, int s, int t) {
	memset(flows, 0, sizeof(long long)*(v+1));
	flows[s] = INT_MAX;
	queue<int> vs;
	for(vs.push(s); !vs.empty() && !flows[t]; vs.pop()) {
		s = vs.front();
		for(int i=0; i++<v; ) {
			if (flows[i] || caps[s][i]<1) continue;
			paths[i] = s; // record vertex i's pre-node s
			vs.push(i);
			flows[i] = min(flows[s], caps[s][i]);
		}
	}
	return flows[t]; // check if it has path to t
}

void edmondskarp(int v, int s, int t) {
	long long flow = 0;
	while(findpath(v, s, t)) {
		// found arguement path, and available flow is curs[t]
		// update available capacity flow
		for(int k=t; k!=s; k=paths[k]) {
			caps[paths[k]][k] -= flows[t];
			caps[k][paths[k]] += flows[t]; // reverse edge
		}
		flow += flows[t];
	}
	printf("%lld\n", flow);
}

int main()
{
	int v, e, s, t, a, b, c; // vertex edge, source -> target
	scanf("%d %d %d %d", &v, &e, &s, &t);
	for(int i=0; i++<e; ) {
		scanf("%d %d %d", &a, &b, &c); // a->b, capacity
		caps[a][b] += c; // a->b may have more than one edge
	}
	edmondskarp(v, s, t);
	return 0;
}
